package com.xh.baselibrary.utils

import android.Manifest
import android.annotation.TargetApi
import android.content.ContentValues
import android.content.Context
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.MediaStore
import com.xh.baselibrary.ex.writeTo
import org.jetbrains.annotations.TestOnly
import java.io.File
import java.io.FileInputStream


/**
 * Note:
 *
 * [Manifest.permission.READ_EXTERNAL_STORAGE]
 * [Manifest.permission.WRITE_EXTERNAL_STORAGE]
 *
 * @author sens 2019/12/26 14:54
 */
@Suppress("unused")
internal object SDCardUtil {

    @TestOnly
    @TargetApi(Build.VERSION_CODES.Q)
    fun saveToPublicDir(context: Context, dir: String, file: File, relativePath: String = ""): Boolean {
        val uri = getPublicDirUri(context, dir, file, relativePath) ?: return false
        return writeTo(context, uri, file)
    }

    @TestOnly
    @TargetApi(Build.VERSION_CODES.Q)
    fun readFromPublicDir(context: Context, dir: String, file: File, relativePath: String = ""): FileInputStream? {
        val uri = getPublicDirUri(context, dir, file, relativePath) ?: return null
        return readFrom(context, uri)
    }

    @TestOnly
    @TargetApi(Build.VERSION_CODES.Q)
    fun deleteFromPublicDir(context: Context, dir: String, file: File, relativePath: String = ""): Boolean {
        val uri = getPublicDirUri(context, dir, file, relativePath) ?: return false
        return context.contentResolver.delete(uri, null, null) > 0
    }

    private fun getPublicDirUri(context: Context, dir: String, file: File, relativePath: String): Uri? {
        return when (dir) {
            Environment.DIRECTORY_DOWNLOADS -> getDownloadUri(context, file, relativePath)
            else -> null
        }
    }

    @TargetApi(Build.VERSION_CODES.Q)
    private fun getDownloadUri(context: Context, file: File, relativePath: String): Uri? {
        val resolver = context.contentResolver
        val values = ContentValues()
        if (relativePath.isEmpty()) {
            values.put(MediaStore.Downloads.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS)
        } else {
            values.put(MediaStore.Downloads.RELATIVE_PATH, File(Environment.DIRECTORY_DOWNLOADS, relativePath).path)
        }
        values.put(MediaStore.Downloads.DISPLAY_NAME, file.name)
        values.put(MediaStore.Downloads.MIME_TYPE, "application/vnd.android.package-archive")
        return resolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, values)
    }

    private fun writeTo(context: Context, uri: Uri, file: File): Boolean {
        try {
            val outputStream = context.contentResolver.openOutputStream(uri) ?: return false
            return file.inputStream().writeTo(outputStream, false)
        } catch (e: Exception) {
            e.printStackTrace()
            return false
        }
    }

    private fun readFrom(context: Context, uri: Uri): FileInputStream? {
        try {
            val pfd = context.contentResolver.openFileDescriptor(uri, "r") ?: return null
            return FileInputStream(pfd.fileDescriptor)
        } catch (e: Exception) {
            return null
        }
    }
}